package com.kingyea.mobilepolice.role.service.impl;

import com.google.common.collect.Lists;
import com.kingyea.mobilepolice.orgrole.bean.OrgRole;
import com.kingyea.mobilepolice.orgrole.bean.OrgRoleCondition;
import com.kingyea.mobilepolice.orgrole.bean.OrgRolePo;
import com.kingyea.mobilepolice.orgrole.dao.OrgRoleMapper;
import com.kingyea.mobilepolice.role.bean.Role;
import com.kingyea.mobilepolice.role.bean.RoleCondition;
import com.kingyea.mobilepolice.role.bean.RolePo;
import com.kingyea.mobilepolice.role.dao.RoleMapper;
import com.kingyea.mobilepolice.role.service.RoleService;
import com.kingyea.mobilepolice.rolepermission.dao.RolePermissionMapper;
import com.kingyea.mobilepolice.security.SecurityUtils;
import com.kingyea.mobilepolice.system.StateCode;
import com.kingyea.mobilepolice.user.bean.User;
import com.kingyea.mobilepolice.user.dao.UserMapper;
import com.kingyea.mobilepolice.userrole.bean.UserRole;
import com.kingyea.mobilepolice.userrole.bean.UserRoleCondition;
import com.kingyea.mobilepolice.userrole.dao.UserRoleMapper;
import com.kingyea.mobilepolice.util.ExceptionConditions;
import com.kingyea.mobilepolice.util.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description Role 实现类
 * @date Created in 2018-03-30 11:36:12
 */
@Service("roleService")
public class RoleServiceImpl implements RoleService {

    private static final Logger LOGGER = LoggerFactory.getLogger(RoleServiceImpl.class);

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private OrgRoleMapper orgRoleMapper;

    /**
     * 通过ID查找对象
     *
     * @param id
     * @return
     */
    @Override
    public Role getById(Integer id) {
        return this.roleMapper.getById(id);
    }

    @Override
    public Role getByName(String name) {
        return this.roleMapper.getByName(name);
    }

    /**
     * 列表
     *
     * @param
     * @return
     */
    @Override
    public List<Role> search(RoleCondition condition) {
        List<Role> list = roleMapper.search(condition);
        return list;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean deleteById(Integer id) {
        rolePermissionMapper.deleteByRoleId(id);
        userRoleMapper.deleteById(id);
        return roleMapper.deleteById(id) > 0;
    }

    /**
     * @Description: 添加角色
     * @Param: [role]
     * @return: boolean
     * @Author: cxc
     * @Date: 2018.04.13 10:35
     */
    @Override
    @Transactional
    public boolean save(Role role) {
        ExceptionConditions.checkNotNull(role, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(role.getRoleName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkIsNull(roleMapper.getByName(role.getRoleName()), StateCode.SERVER_DATA_MISSING_ERROR);

        role.setSerialNo(RandomUtils.genRoleSerialNo());
        role.setCreatedDate(new Date());
        role.setLastUpdatedDate(new Date());
        role.setCreatedBy(SecurityUtils.getCurrentUser().getUserId());
        role.setCreatedByUserName(SecurityUtils.getCurrentUserUsername());
        role.setLastUpdatedByUserName(SecurityUtils.getCurrentUserUsername());
        role.setLastUpdatedBy(SecurityUtils.getCurrentUser().getUserId());
        role.setIsDefault(0);
        ExceptionConditions.checkArgument(roleMapper.save(role) > 0, StateCode.SYSTEM_ERROR);

        UserRole userRole = new UserRole();
        userRole.setCreatedDate(new Date());
        userRole.setLastUpdatedDate(new Date());
        userRole.setUserId(SecurityUtils.getCurrentUser().getUserId());
        userRole.setRoleId(role.getId());
        ExceptionConditions.checkArgument(userRoleMapper.save(userRole) > 0, StateCode.SYSTEM_ERROR);
        return true;
    }

    /**
     * @Description: 修改角色
     * @Param: [role]
     * @return: boolean
     * @Author: cxc
     * @Date: 2018.04.13 10:35
     */
    @Override
    public boolean update(Role role) {
        ExceptionConditions.checkNotNull(role, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(role.getRoleName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(role.getId(), StateCode.NO_ARGUMENT_ERROR);
        Role role_ = roleMapper.getById(role.getId());
        ExceptionConditions.checkNotNull(role_, StateCode.SERVER_DATA_MISSING_ERROR);

        role_.setRoleName(role.getRoleName());
        role_.setDescription(role.getDescription());
        role_.setSort(role.getSort());
        role_.setLastUpdatedBy(SecurityUtils.getCurrentUser().getUserId());
        role_.setLastUpdatedByUserName(SecurityUtils.getCurrentUserUsername());
        role_.setLastUpdatedDate(new Date());
        ExceptionConditions.checkArgument(roleMapper.update(role_) > 0, StateCode.SYSTEM_ERROR);
        return true;
    }

    /**
     * @Description:
     * @Param: [userId]
     * @return: java.util.List<com.kingyea.mobilepolice.role.bean.Role>
     * @Author: cxc
     * @Date: 2018.04.03 10:26
     */
    @Override
    public List<Role> searchByUserId(String userId) {
        UserRoleCondition condition = new UserRoleCondition();
        condition.setPageAble(false);
        condition.setUserId(userId);
        List<UserRole> list = userRoleMapper.search(condition);
//		list.stream().forEach(bean -> System.out.println(JSONObject.toJSONString(bean)));
        /*去重复*/
        Set<Integer> roleIdList = list.stream().map(bean -> bean.getRoleId()).collect(Collectors.toSet());

//		System.out.println(JSONObject.toJSONString(roleIdList));
        List<Role> roleList = Lists.newArrayList();
        if (roleIdList.size() > 0) {
            RoleCondition roleCondition = new RoleCondition();
            roleCondition.setRoleIds(Lists.newArrayList(roleIdList));
            roleCondition.setPageAble(false);
            roleList.addAll(roleMapper.search(roleCondition));
        }
//		roleList.stream().forEach(bean -> System.out.println(JSONObject.toJSONString(bean)));
        return roleList;
    }

    @Override
    public Boolean delRolesForUserId(RolePo po) {
        ExceptionConditions.checkNotNull(po, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(po.getUserId(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(po.getRoleIds(), StateCode.NO_ARGUMENT_ERROR);
        return userRoleMapper.deleteByUserId(po.getUserId(), po.getRoleIds()) >= po.getRoleIds().size();
    }

    @Transactional
    @Override
    public Boolean addRolesForUserId(RolePo po) {
        ExceptionConditions.checkNotNull(po, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(po.getUserId(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(po.getRoleIds(), StateCode.NO_ARGUMENT_ERROR);
//		ExceptionConditions.checkArgument(po.getRoleIds().size() > 0, StateCode.NO_ARGUMENT_ERROR);

        RolePo delPo = new RolePo();
        delPo.setUserId(po.getUserId());
        delPo.setRoleIds(Lists.newArrayList());
        ExceptionConditions.checkArgument(delRolesForUserId(delPo), StateCode.SYSTEM_ERROR);

        User user = userMapper.getByUserId(po.getUserId());
        ExceptionConditions.checkNotNull(user, StateCode.NO_ARGUMENT_ERROR);
        Integer i = 0;
        for (Integer roleId : po.getRoleIds()) {
            UserRole userRole = new UserRole();
            userRole.setUserId(po.getUserId());
            userRole.setRoleId(roleId);
            userRole.setLastUpdatedDate(new Date());
            userRole.setCreatedDate(new Date());
            ExceptionConditions.checkArgument(userRoleMapper.save(userRole) > 0, StateCode.SYSTEM_ERROR);
            i++;
        }
        return i.equals(po.getRoleIds().size());
    }


    @Override
    @Transactional
    public List<Role> searchByOrgSerialNo(OrgRoleCondition condition) {
        condition.setPageAble(false);
        List<OrgRole> orgRoleList = orgRoleMapper.search(condition);
        if (orgRoleList.size() != 0) {
            RoleCondition roleCondition = new RoleCondition();
            roleCondition.setPageSize(condition.getPageSize());
            roleCondition.setPageNum(condition.getPageNum());
            roleCondition.setPageAble(true);
            roleCondition.setRoleIds(orgRoleList.stream().map(OrgRole::getRoleId).collect(Collectors.toList()));
            List<Role> list = roleMapper.search(roleCondition);
            condition.setTotal(roleCondition.getTotal());
            return list;
        }
        return Lists.newArrayList();
    }


    @Override
    @Transactional
    public Boolean updateForOrg(OrgRolePo po) {
        ExceptionConditions.checkNotNull(po, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(po.getRoleIds(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(po.getOrgSerialNo(), StateCode.NO_ARGUMENT_ERROR);
        // 不处理了
        orgRoleMapper.deleteByOrgSerialNo(po.getOrgSerialNo());
        if (po.getRoleIds().size() > 0) {
            return orgRoleMapper.batchSave(po.getRoleIds().stream().map(roleId -> {
                OrgRole orgRole = new OrgRole();
                orgRole.setOrgSerialNo(po.getOrgSerialNo());
                orgRole.setRoleId(roleId);
                return orgRole;
            }).collect(Collectors.toList())) == po.getRoleIds().size();
        }
        return Boolean.TRUE;
    }
}
